import FeatureLoader from '../framework/FeatureLoader';

export default {

  // 检索引用类型的节点
  getRefInst(paramRef, paramSchemaFull, paramSchemaId) {
    let propItemRef;
    let curSchemaFull = paramSchemaFull;
    let curSchemaId = paramSchemaId;
    if (paramRef.indexOf('#/definitions/') !== -1) {
      // 局部引用
      const keyArray = paramRef.split('#/definitions/');
      if (keyArray[0] !== '') {
        // 外部局部引用
        curSchemaId = keyArray[0].split('.')[0];
        //外部引用的全量schema向下传递
        curSchemaFull = FeatureLoader().schemaMap[curSchemaId];
      }
      const defKey = keyArray[1];
      propItemRef = curSchemaFull.definitions[defKey];
    } else if (paramRef.indexOf('.json') !== -1) {
      // 外部全量引用
      curSchemaId = paramRef.split('.')[0];
      propItemRef = FeatureLoader().schemaMap[curSchemaId];

      //外部引用的全量schema向下传递
      curSchemaFull = propItemRef;
    } else {
      debugger;
    }
    return [propItemRef, curSchemaFull, curSchemaId];
  },

  // 检测节点的类型，为分支节点或终端配置项
  checkNodeType(propItem, paramSchemaFull, paramSchemaId) {
    let forkType;
    let forkArrayType = false;
    let refType = false;
    let formType;
    let selectList = [];

    // 将引用类型的对象向下传递
    let refInst;
    // 将外部引用的schema向下传递
    let curSchemaFull = paramSchemaFull;
    let curSchemaId = paramSchemaId;

    if (propItem.type === 'object' && propItem.properties !== undefined) {
      // 普通对象
      forkType = 'fork';
      refInst = propItem;
    } else if (propItem.$ref) {
      // 对象引用
      let propItemRef;
      [propItemRef, curSchemaFull, curSchemaId] = this.getRefInst(propItem.$ref, paramSchemaFull, paramSchemaId);
      if (propItemRef === undefined) {
        debugger;
        return {};
      }

      if (propItemRef.type) {
        // 引用类型，对象引用
        forkType = 'fork';
        refType = true;
        refInst = propItemRef;
      } else if (propItemRef.enum) {
        // 引用类型，且为枚举
        forkType = 'leaf';
        formType = 'select';
        selectList = propItemRef.enum.map(item => {
          if (typeof item === 'string') {
            return {
              id: item,
              name: item,
            };
          } else {
            return item;
          }
        });
      } else if (propItemRef.anyOf && propItemRef.anyOf.length > 0) {
        // 可变类型
        forkType = 'anyOf';
        refInst = propItemRef.anyOf;
      } else {
        debugger;
      }
    } else if (propItem.type === 'array' && propItem.items.$ref) {
      // 数组类型，且为对象引用
      let propItemRef;
      [propItemRef, curSchemaFull, curSchemaId] = this.getRefInst(propItem.items.$ref, paramSchemaFull, paramSchemaId);
      if (propItemRef === undefined) {
        debugger;
        return {};
      }

      if (propItemRef.type) {
        propItemRef.title = propItem.title;
        forkType = 'fork';
        refType = true;
        forkArrayType = true;
        refInst = propItemRef;
      }
    } else if (propItem.type === 'array' && propItem.items) {
      if (propItem.items.type === 'object') {
        // 数组类型，且为普通对象
        forkType = 'fork';
        forkArrayType = true;
        refInst = propItem.items;
      } else if (propItem.items.type === 'string') {
        // 数组类型，且为字符数组
        forkType = 'leaf';
        formType = 'selectMulti';
      } else {
        debugger;
      }
    } else if (propItem.anyOf && propItem.anyOf.length > 0) {
      // 可变类型
      forkType = 'anyOf';
      refInst = propItem.anyOf;
    } else if (propItem.type === 'string') {
      // 字符、数值类型
      forkType = 'leaf';
      formType = 'input';
    } else if (propItem.type === 'integer' || propItem.type === 'number') {
      // 字符、数值类型
      forkType = 'leaf';
      formType = 'inputNumber';
    } else if (propItem.type === 'boolean') {
      // bool类型
      forkType = 'leaf';
      formType = 'switch';
    } else if (propItem.const) {
      // const类型
      forkType = 'leaf';
      formType = 'label';
      selectList = [{
        id: propItem.const,
        name: propItem.const,
      }];
    } else {
      debugger;
    }
    return { forkType, forkArrayType, refType, formType, selectList, refInst, curSchemaFull, curSchemaId };
  },

  // 构建配置项动态表单数据
  getArrayCfgList(schemaObj, paramSchemaFull, paramSchemaId) {
    // 准备必填项map
    const requireMap = {};
    if (schemaObj.required && schemaObj.required.length > 0) {
      schemaObj.required.forEach(item => {
        requireMap[item] = true;
      });
    }

    const retCfgList = [];
    for (const key in schemaObj.items.properties) {
      if (Object.hasOwnProperty.call(schemaObj.items.properties, key)) {
        const propItem = schemaObj.items.properties[key];
        const typeObj = this.checkNodeType(propItem, paramSchemaFull, paramSchemaId);
        if (typeObj.forkType === 'leaf') {
          const tailTitle = requireMap[key] ? `(required)` : '';
          const tmpObj = {
            description: propItem.description || key,
            required: requireMap[key],
            formLabel: `${propItem.title || key}${tailTitle}`,
            formType: typeObj.formType,
            modelKey: key,
            selectList: typeObj.selectList,
          };
          retCfgList.push(tmpObj);
        }
      }
    }
    return retCfgList;
  },

  // 构建配置项动态表单数据
  getCfgList(schemaObj, paramSchemaFull, paramSchemaId) {
    // 准备必填项map
    const requireMap = {};
    if (schemaObj.required && schemaObj.required.length > 0) {
      schemaObj.required.forEach(item => {
        requireMap[item] = true;
      });
    }

    const retCfgList = [];
    for (const key in schemaObj.properties) {
      if (key === 'common') {
        continue;
      }
      if (Object.hasOwnProperty.call(schemaObj.properties, key)) {
        const propItem = schemaObj.properties[key];
        const typeObj = this.checkNodeType(propItem, paramSchemaFull, paramSchemaId);
        if (typeObj.forkType === 'leaf') {
          const tailTitle = requireMap[key] ? `(required)` : '';
          const tmpObj = {
            description: propItem.description || key,
            required: requireMap[key],
            formLabel: `${propItem.title || key}${tailTitle}`,
            formType: typeObj.formType,
            modelKey: key,
            selectList: typeObj.selectList,
          };
          retCfgList.push(tmpObj);
        }
      }
    }
    return retCfgList;
  },

  // 解析节点，递归方法
  parseNode(pMetaObj, schemaObj, paramSchemaFull, paramSchemaId) {
    // 准备必填项map
    const requireMap = {};
    if (schemaObj.required && schemaObj.required.length > 0) {
      schemaObj.required.forEach(item => {
        requireMap[item] = true;
      });
    }

    const curChildren = [];
    for (const key in schemaObj.properties) {
      if (key === 'common') {
        continue;
      }
      if (Object.hasOwnProperty.call(schemaObj.properties, key)) {
        const propItem = schemaObj.properties[key];
        const typeObj = this.checkNodeType(propItem, paramSchemaFull, paramSchemaId);

        if (typeObj.forkType !== 'fork' && typeObj.forkType !== 'anyOf') {
          continue;
        }

        const tmpNode = this.genTreeNode(key, typeObj, pMetaObj);
        if (tmpNode) {
          tmpNode.required = requireMap[key];
          curChildren.push(tmpNode);
        }
      }
    }
    return curChildren;
  },

  // 生成节点
  genTreeNode(key, typeObj, pMetaObj) {
    const propItemInst = typeObj.refInst;
    const paramSchemaFull = typeObj.curSchemaFull;
    const paramSchemaId = typeObj.curSchemaId;

    let children = [];
    let tailTitle = '';

    // 非空节点
    if (pMetaObj[key] !== undefined) {
      if (typeObj.forkType === 'anyOf') {
        const tmpName = key.split('_')[1];
        const tmpKey = `$_${tmpName}_type`;
        const tmpValue = pMetaObj[tmpKey];
        const tmpInst = propItemInst.find(item => {
          return item.properties.name.const === tmpValue;
        });
        if (tmpInst) {
          children = this.parseNode(pMetaObj[key], tmpInst, paramSchemaFull, paramSchemaId);
        }
      } else if (!typeObj.forkArrayType) {
        children = this.parseNode(pMetaObj[key], propItemInst, paramSchemaFull, paramSchemaId);
      } else {
        // 拼装数组子节点
        children = pMetaObj[key].map((item, i) => {
          const subChildren = this.parseNode(item, propItemInst, paramSchemaFull, paramSchemaId);
          const subTitle = subChildren.length > 0 ? `{${subChildren.length}}` : '';
          const propIndex = propItemInst.format ? item[propItemInst.format] : null;
          return {
            title: propIndex || `$inst_${i} ${subTitle}`,
            description: propItemInst.description || `数组索引_${i}`,
            nodeName: i,
            forkArrayInner: true,
            schemaBlock: typeObj.refInst,
            attachPoint: item || {}, // 默认内部类型为对象
            parentPoint: pMetaObj[key],
            nodeIcon: 'md-cube',
            expand: true,
            children: subChildren,

            nodeTypeObj: typeObj,
          };
        });
      }

      tailTitle = typeObj.forkArrayType ? `[${children.length}]` : children.length > 0 ? `{${children.length}}` : '';
    }

    const tmpTitle = typeObj.forkType === 'anyOf' ? '实例属性' : null;

    const retNode = {
      title: tmpTitle || `${propItemInst.title || key} ${tailTitle}`,
      description: propItemInst.description || key,
      nodeName: key,
      forkArrayOuter: typeObj.forkArrayType,
      schemaBlock: typeObj.refInst,
      attachPoint: pMetaObj[key],
      parentPoint: pMetaObj,
      nodeIcon: 'md-cube',
      expand: true,
      children: children,

      nodeTypeObj: typeObj,
    };

    if (typeObj.forkArrayType) {
      retNode.nodeIcon = 'md-list';
    }

    return retNode;
  },
};